<?php
// +----------------------------------------------------------------------
// | SwiftPHP [ JUST DO ONE THING WELL ]
// +----------------------------------------------------------------------
// | Copyright (c) 2015-2017  http://swiftphp.zhongwenyu.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: zhongwenyu <zhongwenyu1987@163.com> <http://www.zhongwenyu.com>
// +----------------------------------------------------------------------
// | Times: 2017/2/23 10:27
// +----------------------------------------------------------------------
namespace swift;

class View{
    // 视图输出实例
    protected static $instance;
    // 视图输出替换
    protected $replace = [];
    // 模板引擎实例
    protected $template;
    // 视图输出数据
    protected $data = [];
    // 模板引擎参数
    protected $config = [];

    /**
     * 架构函数
     * @access public
     * @param array $config  模板引擎配置参数
     * @param array $replace  字符串替换参数
     */
    public function __construct($config = [], $replace = []){
        $this->config = array_merge($this->config , $config);
        if(empty($this->config['view_path'])){
            $this->config['view_path'] = App::$modulePath . 'view' . DS;
        }
        // 实例化模板引擎
        $this->template = new Template($this->config);
    }

    /**
     * 初始化视图
     * @access public
     * @param array $config  模板引擎配置参数
     * @param array $replace  字符串替换参数
     * @return object
     */
    public static function instance($config = [] , $replace = []){
        if(is_null(self::$instance)){
            self::$instance = new self($config , $replace);
        }
        return self::$instance;
    }

    /**
     * 模板变量赋值
     * @access public
     * @param mixed $name  变量名
     * @param mixed $value 变量值
     * @return $this
     */
    public function assign($name, $value = '')
    {
        if (is_array($name)) {
            $this->data = array_merge($this->data, $name);
        } else {
            $this->data[$name] = $value;
        }
        return $this;
    }

    /**
     * 解析和获取模板内容 用于输出
     * @param string    $template 模板文件名或者内容
     * @param array     $vars     模板输出变量
     * @return string
     * @throws Exception
     */
    public function fetch($template = '', $vars = []){
        // 模板变量
        $vars = array_merge($this->data , $vars);

        // 开启输出缓冲
        ob_start();
        // 关闭绝对刷新
        ob_implicit_flush(0);

        // 配置模板文件
        $template = $this->parseTemplate($template);
        // 渲染输出
        $content = $this->template->fetch($template , $vars);

        // 清空视图输出数据
        $this->data = [];

        return $content;
    }

    /**
     * 自动定位模板文件
     * @param string    $template 模板文件名
     * @return string   $path  模板文件地址
     * @throws Exception
     */
    protected function parseTemplate($template){
        if('' == pathinfo($template , PATHINFO_EXTENSION)){
            $request = Request::instance();
            // 跨模块调用
            if(strpos($template , '@')){
                list($module , $template) = explode('@' , $template);
            }
            $path = isset($module) ? APP_PATH . $module . DS . 'view' . DS : $this->config['view_path'];
            $depr = $this->config['view_depr'];
            if(!empty($template)){
                $template = trim($template , '/');
                if(strpos($template , '/')){
                    // 控制器/操作
                    $template   = str_replace(['/', ':'], $depr, $template);
                }else{
                    $template = $request->controller() . $depr . $template;
                }
            }else{
                // 模板文件名为空，按照默认定义
                $template = $request->controller() . $depr . $request->action();
            }
            $template = $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.');
        }
        if(!is_file($template)){
            throw new \Exception('模板文件'.$template.'不存在！');
        }
        return $template;
    }
}